package com.xiyu.service.service.customer;

import com.xiyu.service.framework.security.core.util.SecurityFrameworkUtils;
import com.xiyu.service.model.customer.info.CustomerInfo;
import com.xiyu.service.model.system.dept.SystemUserPost;
import com.xiyu.service.model.system.permission.SystemUserRole;
import com.xiyu.service.model.system.user.SystemUser;
import com.xiyu.service.repository.customer.info.CustomerInfoRepository;
import com.xiyu.service.repository.system.dept.SystemUserPostRepository;
import com.xiyu.service.repository.system.user.SystemUserRepository;
import com.xiyu.service.service.setting.PoolSettingService;
import com.xiyu.service.vo.customer.customer.CustomerErrorMessage;
import com.xiyu.service.vo.customer.customerPool.CustomerPoolAllocationOutput;
import com.xiyu.service.vo.customer.customerPool.CustomerPoolAllocationInput;
import com.xiyu.service.vo.customer.customerPool.CustomerPoolReceiveOutput;
import com.xiyu.service.vo.customer.customerPool.CustomerPoolReceiveInput;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.util.*;

import org.springframework.transaction.annotation.Transactional;
import com.xiyu.service.util.entity.EntityUtils;
import com.xiyu.service.framework.web.web.core.pojo.PageResult;
import com.xiyu.service.convert.customer.CustomerPoolConvert;

import static com.xiyu.service.errorCode.customer.CustomerErrorCode.CUSTOMER_INFO_NOT_EXIST;
import static com.xiyu.service.errorCode.system.user.UserErrorCode.USER_NOT_EXISTS;
import static com.xiyu.service.framework.exception.util.ServiceExceptionUtil.exception;
import static com.xiyu.service.errorCode.customer.CustomerPoolErrorCode.*;

/**
 * 公海客户 Service 实现类
 */
@Service
@Validated
public class CustomerPoolServiceImpl implements CustomerPoolService {

    @Resource
    private CustomerInfoRepository customerInfoRepository;

    @Resource
    private SystemUserRepository systemUserRepository;

    @Resource
    private SystemUserPostRepository systemUserPostRepository;

    @Resource
    private PoolSettingService poolSettingService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<CustomerPoolReceiveOutput> receive(CustomerPoolReceiveInput inputVO) {
        List<CustomerErrorMessage> errorMessages = allocationCustomer(inputVO.getIds(), SecurityFrameworkUtils.getLoginUserId());
        return CustomerPoolConvert.INSTANCE.receiveOutPutConvert(errorMessages);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<CustomerPoolAllocationOutput> allocation(CustomerPoolAllocationInput inputVO) {
        List<CustomerErrorMessage> errorMessages = allocationCustomer(inputVO.getIds(), inputVO.getOwnerId());
        return CustomerPoolConvert.INSTANCE.allocationOutPutConvert(errorMessages);
    }

    private List<CustomerErrorMessage> allocationCustomer(List<Long> ids, Long ownerId){
        Long availableCount = poolSettingService.getUserAvailableCount(ownerId);
        SystemUser systemUser = systemUserRepository.findNullable(ownerId);
        if(systemUser == null){
            throw exception(USER_NOT_EXISTS);
        }
        Long deptId = systemUser.deptId();
        List<CustomerErrorMessage> errorMessage = new ArrayList<>();
        for(Long id : ids){
            CustomerInfo customerInfo = customerInfoRepository.findNullable(id);
            if(customerInfo == null){
                errorMessage.add(new CustomerErrorMessage(id, "", "", CUSTOMER_INFO_NOT_EXIST.getMsg()));
                continue;
            }
            if(availableCount != null && availableCount <= 0){
                errorMessage.add(new CustomerErrorMessage(id, customerInfo.name(), customerInfo.customerNo(), CUSTOMER_POOL_MAX_LIMIT.getMsg()));
                continue;
            }
            // 判断客户是否已经不在公海
            if(customerInfo.isFallPool().equals(false)){
                errorMessage.add(new CustomerErrorMessage(id, customerInfo.name(), customerInfo.customerNo(), CUSTOMER_POOL_NO_IN_POOL.getMsg()));
                continue;
            }
            // 更新所属人
            customerInfoRepository.allocation(id, ownerId, deptId);
            if(availableCount != null)
                availableCount --;
        }

        return errorMessage;
    }

}
